﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using Thor.Domain;
using Thor.Domain.Configuration;

namespace Thor.Repository.Azure.Table
{
    /// <summary>
    /// A repository that stores setting entities.
    /// </summary>
    public class SettingsRepository : TableRepositoryBase, ISettingsRepository
    {
        #region Fields

        private SettingsContext _context;

        #endregion

        #region Constructors

        public SettingsRepository(Dictionary<string, object> repositoryParameters)
            : base(repositoryParameters)
        {
            _context = new SettingsContext(StorageAccount.TableEndpoint.AbsoluteUri, StorageAccount.Credentials);
        }

        #endregion

        #region ISettingsRepository Members

        /// <summary>
        /// Inserts a new settings entity into the repository.
        /// </summary>
        /// <param name="settings"></param>
        public void Insert(Settings settings)
        {
            _context.Insert(CreateRowFromSettings(settings));
        }

        /// <summary>
        /// Updates a settings entity in the repository.
        /// </summary>
        /// <param name="settings"></param>
        public void Update(Settings settings)
        {
            _context.Update(CreateRowFromSettings(settings));
        }

        /// <summary>
        /// Deletes a settings entity from the repository.
        /// </summary>
        /// <param name="settings"></param>
        public void Delete(Settings settings)
        {
            _context.Delete(CreateRowFromSettings(settings));
        }

        /// <summary>
        /// Retrieves a settings record from the repository.
        /// </summary>
        /// <returns></returns>
        public Settings Fetch()
        {
            SettingsRow row = _context.GetRow();

            if (row != null)
                return CreateSettingsFromRow(row);
            else
                return null;
        }

        /// <summary>
        /// Creates a row from the POCO object.
        /// </summary>
        /// <param name="settings"></param>
        /// <returns></returns>
        private SettingsRow CreateRowFromSettings(Settings settings)
        {
            return new SettingsRow()
            {
                ApplicationName = ApplicationName,
                BookingAgentEmail = settings.BookingAgentEmail,
                CalendarProviderUri = settings.CalendarProviderUri,
                LockoutDuration = settings.LockoutDuration,
                Password = settings.Password,
                RetryCount = settings.RetryCount,
                RetryInterval = settings.RetryInterval,
                UseBookingAgent = settings.UseBookingAgent,
                UserName = settings.UserName,
                PartitionKey = this.ApplicationName,
                RowKey = settings.SettingsId.ToString(),
                AssemblyName = settings.AssemblyName,
                AssemblyType = settings.AssemblyType,
                ServerTimeZone = settings.ServerTimeZone,
                IsEncrypted = settings.IsEncrypted
            };
        }

        /// <summary>
        /// Creates a POCO object from the row.
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        private Settings CreateSettingsFromRow(SettingsRow row)
        {
            Settings settings = new Settings(row.IsEncrypted);

            settings.BookingAgentEmail = row.BookingAgentEmail;
            settings.CalendarProviderUri = row.CalendarProviderUri;
            settings.UserName = row.UserName;
            settings.Password = row.Password;
            settings.LockoutDuration = row.LockoutDuration;
            settings.RetryCount = row.RetryCount;
            settings.RetryInterval = row.RetryInterval;
            settings.UseBookingAgent = row.UseBookingAgent;
            settings.AssemblyName = row.AssemblyName;
            settings.AssemblyType = row.AssemblyType;
            settings.ServerTimeZone = row.ServerTimeZone;

            return settings;
        }

        #endregion
    }
}
